package org.thomias.exo3.map;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URI;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

public class FTPMap implements Map<String, String> {

	private URI uri;
	private FTPClient ftp;
	private String hostname;
	private String login;
	private String password;
	private String pathname;

	public FTPMap(URI uri) {
		this.uri = uri;
		this.ftp = new FTPClient();
		this.hostname = this.uri.getHost();
		String[] a = this.uri.getUserInfo().split(":");
		this.login = a[0];
		this.password = a[1];
		System.out.println(login);
		System.out.println(password);
		this.pathname = this.uri.getPath();
		System.out.println(pathname);
		checkConnection();
	}

	private void checkConnection() {
		if (ftp.isConnected() == false) {
			try {
				debug("Reconnect");
				try {
					ftp.disconnect();
				} catch (Exception e) {
				}
				ftp.connect(hostname);
				ftp.enterLocalPassiveMode();
				ftp.login(login, password);
				int reply = ftp.getReplyCode();
				if (!FTPReply.isPositiveCompletion(reply)) {
					throw new Exception("Cannot connect");
				}
				boolean b = ftp.changeWorkingDirectory(pathname);
				debug("b=" + b);
				if (b == false) {
					ftp.makeDirectory(pathname);
					b = ftp.changeWorkingDirectory(pathname);
					debug("b=" + b);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	private void debug(String string) {
		System.out.println(string);

	}

	@Override
	public int size() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean containsKey(Object key) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean containsValue(Object value) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public String get(Object key) {
		checkConnection();
		InputStream f = null;
		String result;
		try {
			f = ftp.retrieveFileStream((String) key);
			if (f == null) {
				debug("f is NULL");
				return null;
			}
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] read = new byte[1024];
			int len = 0;
			while ((len = f.read(read, 0, read.length)) != -1) {
				baos.write(read, 0, len);
			}
			result = new String(baos.toByteArray());
			baos.close();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {

			try {
				ftp.completePendingCommand();
				if (f != null) {
					f.close();
				}
			} catch (Exception e2) {
			}

		}

		return result;
	}

	@Override
	public String put(String key, String value) {
		try {
			checkConnection();
			byte[] a = value.getBytes();
			ByteArrayInputStream bais = new ByteArrayInputStream(a);
			ftp.storeFile(key, bais);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public String remove(Object key) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void putAll(Map<? extends String, ? extends String> m) {
		// TODO Auto-generated method stub

	}

	@Override
	public void clear() {
		// TODO Auto-generated method stub

	}

	@Override
	public Set<String> keySet() {
		checkConnection();
		Set<String> result = new LinkedHashSet<String>();
		try {
			FTPFile[] fileList = ftp.listFiles();
			Arrays.sort(fileList, new Comparator<FTPFile>() {
				@Override
				public int compare(FTPFile f1, FTPFile f2) {

					return f1.getName().compareTo(f2.getName());
				}
			});
			for (int i = 0; i < fileList.length; i++) {
				if (fileList[i].isFile()) {
					String fileName = fileList[i].getName();

					result.add(fileName);

				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;
	}

	@Override
	public Collection<String> values() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Set<java.util.Map.Entry<String, String>> entrySet() {
		// TODO Auto-generated method stub
		return null;
	}

}
